home *** CD-ROM | disk | FTP | other *** search
-
- Proclaimed functions of a fixed number of args are much more
- efficient. It is still possible to pass multiple values
- efficiently (but not quite with the CL semantics)
-
- Here are two examples, one using ordinary multiple-value-setq
- and the other our-multiple-value-setq.
- For 1,000,000 calls:
-
- Type : CL 2 values our 2 values 1 value
- Time : 7.9 sec 3.5 2.35
- name : foo-mv foo-our-mv foo
- Uses : multiple-value-setq our-multiple-value-setq Only 1 value passed.
-
- (defun foo-mv (n)
- (let (x y)
- (sloop for i below n
- do (multiple-value-setq(x y) (goo-mv)))))
-
- (defun goo-mv () (values 1 2))
-
-
- And then an equivalent one:
- (proclaim '(function foo-our-mv (t) t))
- (proclaim '(function goo-our-mv () t))
- (defun foo-our-mv (n)
- (let (x y)
- (sloop for i below n
- do (our-multiple-value-setq (x y) (goo-our-mv)))
- (list x y)))
-
- (defun goo-our-mv () (our-values 1 2))
-
- The times:
- >(time (foo-our-mv 1000000))
- real time : 3.617 secs
- run time : 3.583 secs
- (1 2)
- >(time (foo-mv 1000000))
- real time : 8.033 secs
- run time : 7.800 secs
- (1 2)
-
- Here are the our-mv macros:
-
- (use-package "SLOOP")
-
-
- (defmacro our-values (a &rest l)
- (or (< (length l) (length *vals*)) (error "too many values"))
- `(prog1 ,a ,@ (sloop for v in l
- for u in *vals*
- collect `(setq ,u ,v))))
-
- (defmacro our-multiple-value-setq ((x &rest l) form)
- (or (< (length l) (length *vals*)) (error "too many values"))
- `(prog1 (setq ,x ,form)
- ,@ (sloop for w in *vals*
- for v in l
- collect `(setq ,v ,w))))
-
- (defvar *vals*
- '(*val1* *val2* *val3* *val4* *val5* *val6* *val7* *val8* *val9* *val10*))
-
-
- (defvar *val1* nil)
- (defvar *val2* nil)
- (defvar *val3* nil)
- (defvar *val4* nil)
- (defvar *val5* nil)
- (defvar *val6* nil)
- (defvar *val7* nil)
- (defvar *val8* nil)
- (defvar *val9* nil)
- (defvar *val10* nil)
-
- ;; Note that this method does not penalize ordinary calls at all.
- ;; It is not the same as the common lisp multiple values in general:
- ;; 1) The information on how many values are being passed is not
- ;; recorded [ unless of course that number is one of the values ! ]
- ;; 2) If you ask for more values than were specified you will get
- ;; a random value. Common lisp values would say you get nil.
- ;; Now it is true that it would be possible to make AKCL pass multiple
- ;; values more efficiently, but this is really a large overhaul of the
- ;; system. There are lots of system functions, hand coded using the
- ;; old scheme. I have been thinking about ways to do this for the
- ;; last little while, but have not settled on anything.
-
- Bill
-
-
-
-
-
-